package com.ant.storage.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ant.storage.common.Constants;
import com.ant.storage.common.ResultVo;
import com.ant.storage.pojo.*;
import com.ant.storage.service.*;
import com.ant.storage.utils.DingCallbackCrypto;
import com.ant.storage.utils.DingDingUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiProcessInstanceTerminateRequest;
import com.dingtalk.api.response.OapiProcessInstanceTerminateResponse;
import com.taobao.api.ApiException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/DingDing")
@Api(tags = "钉钉接口")
public class DingDingController {

    private static Logger logs = LoggerFactory.getLogger(DingDingController.class);

    @Autowired
    IAllocationService allocationService;

    @Autowired
    IGoodsPoolService goodsPoolService;

    @Autowired
    ISubscribeService subscribeService;

    @Autowired
    IAllocationWarehouseOutService allocationWarehouseOutService;

    @Autowired
    IUserService userService;

    @Autowired
    IPickingService pickingService;

    @Autowired
    IAuditListService auditListService;

    @Autowired
    IPurchaserRecordService recordService;

    @Autowired
    IHouseLeaseService leaseService;

    @Autowired
    IInvoiceInfoService infoService;

    @Autowired
    IErrMsgService msgService;

    @RequestMapping("/CallBack")
    public Map<String, String> callBack(
            @RequestParam(value = "msg_signature", required = false) String msg_signature,
            @RequestParam(value = "timestamp", required = false) Long timeStamp,
            @RequestParam(value = "nonce", required = false) String nonce,
            @RequestBody(required = false) JSONObject json) throws DingCallbackCrypto.DingTalkEncryptException,
            ApiException {
        System.out.println("------------------进入回调-----------------");
        try {
            // 1. 从http请求中获取加解密参数
            // 2. 使用加解密类型
            // Constant.OWNER_KEY 说明：
            // 1、开发者后台配置的订阅事件为应用级事件推送，此时OWNER_KEY为应用的APP_KEY。
            // 2、调用订阅事件接口订阅的事件为企业级事件推送，
            //      此时OWNER_KEY为：企业的appkey（企业内部应用）或SUITE_KEY（三方应用）
            DingCallbackCrypto callbackCrypto = new DingCallbackCrypto("KowBhy",
                    "9OLcbM93KsPMFS5vAJINgSVq87tIt4Sc4ZSLlo6meoi",
                    "dinge7unikff6wyexy1v");

//            DingCallbackCrypto callbackCrypto = new DingCallbackCrypto("ZS2uMrtMk3LGA9EgqozqPQ8xAGIyP5iuD97FDpq4PWaROGVY4oLW",
//                    "JYF1oMRBWP3LibUqLWsOxiA0B1lll4Fltoi4dihAYtv", "dingu4vbubjjibqwiq1w");
            String encryptMsg = json.getString("encrypt");
            System.out.println("code=>"+encryptMsg);
            String decryptMsg = callbackCrypto.getDecryptMsg(msg_signature, timeStamp.toString(), nonce, encryptMsg);
            System.out.println("decryptMsg=>"+decryptMsg);


            // 3. 反序列化回调事件json数据
            JSONObject eventJson = JSON.parseObject(decryptMsg);
            System.out.println("code=>"+eventJson);
            ErrMsg msg=new ErrMsg();
            msg.setCreationTime(new Date());
            msg.setErrValue(eventJson.toString());
            msg.setErrCode("201");
            msgService.save(msg);

            String eventType = eventJson.getString("EventType");
            System.out.println("eventType=>"+eventType);
            // 4. 根据EventType分类处理
            //EventType为bpms_instance_change审批实例
            //type为finish 审批实例结束
            //System.out.println(eventJson);
            String processInstanceId = eventJson.getString("processInstanceId");
            //  实例状态变更类型： start：审批实例开
            // finish：审批正常结束（同意或拒绝）
            // terminate：审批终止（发起人撤销审批单）
            String type = eventJson.getString("type");
            // 审批结果：
            // agree：同意
            // refuse：拒绝
            String result = eventJson.getString("result");
            // if ("bpms_instance_change".equals(eventType) && "finish".equals(eventJson.getString("type"))) {
            if ("bpms_task_change".equals(eventType) || "bpms_instance_change".equals(eventType)) {
                // if(type.equals("finish") || result.equals("redirect")) {
                //   CarReimbursementVo carReimbursementVo = carReimbursementDao.findCarReimbursement
                //   (processInstanceId);
                if (type.equals("finish")) {
                    if (eventJson.getString("processCode").equals(Constants.ALLOCATION_PROCESSCODE)) {
                        Allocation allocation = new Allocation();
                        UpdateWrapper<Allocation> wrapper = new UpdateWrapper<>();
                        wrapper.eq("process_instance_id", eventJson.getString("processInstanceId"));
                        if (eventJson.getString("result").equals("agree")) {
                            allocation.setAllocation_type("3");
                            allocationService.update(allocation, wrapper);
                            Allocation allocation1 = allocationService.getOne(wrapper);
                            AllocationWarehouseOut allocationWarehouseOut = new AllocationWarehouseOut();
                            allocationWarehouseOut.setAllocation_id(allocation1.getAllocation_id());
                            allocationWarehouseOut.setAllocation_warehouse_out_type(1);
                            allocationWarehouseOutService.save(allocationWarehouseOut);
                        }
                        if (eventJson.getString("result").equals("refuse")) {
                            allocation.setAllocation_type("4");
                            allocationService.update(allocation, wrapper);
                        }
                    }
                    //修改采购申请单状态
                    if (eventJson.getString("processCode").equals(Constants.ALLOCATION_PURCHASE_REQUISITION)) {
                        String user_id = eventJson.getString("staffId");
                        GoodsPool goodsPool = new GoodsPool();
                        AuditList auditList = new AuditList();
                        UpdateWrapper<GoodsPool> wrapper = new UpdateWrapper<>();
                        wrapper.eq("process_instance_id", eventJson.getString("processInstanceId"));
                        // 查询审核表 返回id 通过id修改数据
                        AuditList auditId = goodsPoolService.selectIsAudit(processInstanceId, user_id);
                        if (eventJson.getString("result").equals("agree")) {
                            if (auditId != null) {
                                //通过id修改数据
                                auditList.setId(auditId.getId());
                                auditList.setStatus(2);
                                auditList.setOpinion(eventJson.getString("remark"));
                                auditListService.updateById(auditList);
                                if (auditListService.getAllPassed(auditId.getParentId(), "goodsPool")) {
                                    goodsPool.setApplyStatus(2);
                                    goodsPoolService.update(goodsPool, wrapper);
                                    goodsPoolService.getprocessInstanceIdById(eventJson.getString("processInstanceId"));
                                }
                                logs.info("通过审批->" + user_id + ":" + eventJson.getString("remark"));
                            }
                        }
                        if (eventJson.getString("result").equals("refuse")) {
                            goodsPool.setApplyStatus(2);
                            goodsPoolService.update(goodsPool, wrapper);
                            auditList.setId(auditId.getId());//通过id修改数据
                            auditList.setStatus(1);
                            auditList.setOpinion(eventJson.getString("remark"));
                            auditListService.updateById(auditList);
                        }
                    }

                    //修改请款状态
                    if (eventJson.getString("processCode").equals(Constants.ALLOCATION_PURCHASE_PURCHASE)) {
                        String user_id = eventJson.getString("staffId");
                        AuditList auditList = new AuditList();
                        String opinion = eventJson.getString("result");
                        AuditList auditId = subscribeService.selectIsAudit(processInstanceId, user_id);
                        if (auditId != null) {
                            auditList.setId(auditId.getId());
                            auditList.setStatus(2);
                            auditList.setOpinion(eventJson.getString("remark"));
                            auditListService.updateById(auditList);
                            // 是否全部通过
                            if (auditListService.getAllPassed(auditId.getParentId(), "payment")) {
                                subscribeService.getprocessInstanceIdById(eventJson.getString("processInstanceId"),
                                        opinion);
                            }
                            logs.info("通过审批->" + user_id + ":" + eventJson.getString("remark"));
                        }
                    }

                    //请款
                    if (eventJson.getString("processCode").equals(Constants.ALLOCATION_PURCHASE_REQUESTFUNDS)) {
                        String user_id = eventJson.getString("staffId");
                        AuditList auditList = new AuditList();
                        String opinion = eventJson.getString("result");
                        AuditList auditId = infoService.selectIsAudit(processInstanceId, user_id);
                        if (auditId != null) {
                            auditList.setId(auditId.getId());
                            auditList.setStatus(opinion.equals("agree") ? 2 : 1);
                            auditList.setOpinion(eventJson.getString("remark"));
                            auditListService.updateById(auditList);
                            // 是否全部通过
                            if (auditListService.getAllPassed(auditId.getParentId(), "funds")) {
                                infoService.getprocessInstanceIdById(eventJson.getString("processInstanceId"), opinion);
                            } else {
                                if (opinion.equals("refuse")) {
                                    infoService.update(new UpdateWrapper<InvoiceInfo>()
                                            .set("audit_status", 2)
                                            .eq("process_instance_id", processInstanceId));
                                }
                            }

                            logs.info("通过审批->" + user_id + ":" + eventJson.getString("remark"));
                        }
                    }

                    //修改报销状态
                    if (eventJson.getString("processCode").equals(Constants.ALLOCATION_PURCHASE_REIMBURSEMENT)) {
                        String user_id = eventJson.getString("staffId");
                        AuditList auditList = new AuditList();
                        String opinion = eventJson.getString("result");
                        AuditList auditId = recordService.selectIsAudit(processInstanceId, user_id);
                        if (auditId != null) {
                            auditList.setId(auditId.getId());
                            auditList.setStatus(opinion.equals("agree") ? 2 : 1);
                            auditList.setOpinion(eventJson.getString("remark"));
                            auditListService.updateById(auditList);
                            // 是否全部通过
                            if (auditListService.getAllPassed(auditId.getParentId(), "reimbursement")) {
                                recordService.recordApproved(eventJson.getString("processInstanceId"), opinion);
                            } else {
                                if (opinion.equals("refuse")) {
                                    recordService.update(new UpdateWrapper<PurchaserRecord>()
                                            .set("nailing_status", opinion.equals("agree") ? 1 : 2)
                                            .eq("process_instance_id", processInstanceId));
                                }
                            }
                            if (auditListService.getAllPassed(auditId.getParentId(), "rent_review")) {
                                infoService.getprocessInstanceIdByIds(eventJson.getString("processInstanceId"),
                                        opinion);
                            } else {
                                if (opinion.equals("refuse")) {
                                    infoService.update(new UpdateWrapper<InvoiceInfo>()
                                            .set("audit_status", 2)
                                            .eq("process_instance_id", processInstanceId));
                                }
                            }
                        }
                    }

                    //修改领取审核状态
                    if (eventJson.getString("processCode").equals(Constants.ALLOCATION_PICKING_REIMBURSEMENT)) {
                        String user_id = eventJson.getString("staffId");
                        AuditList auditId = pickingService.selectIsAudit(processInstanceId, user_id);
                        if (auditId != null) {
                            AuditList auditList = new AuditList();
                            auditList.setId(auditId.getId());
                            Picking picking = new Picking();
                            UpdateWrapper<Picking> wrapper = new UpdateWrapper<>();
                            wrapper.eq("process_instance_id", eventJson.getString("processInstanceId"));

                            if (eventJson.getString("result").equals("agree")) {
                                auditList.setOpinion(eventJson.getString("remark"));
                                auditList.setStatus(2);
                                auditListService.updateById(auditList);

                                if (auditListService.getAllPassed(auditId.getParentId(), "picking")) {
                                    picking.setAuditStatus(2);
                                    pickingService.update(picking, wrapper);
                                }
                                logs.info("通过审批->" + user_id + ":" + eventJson.getString("remark"));
                            }
                            if (eventJson.getString("result").equals("refuse")) {
                                auditList.setId(auditId.getId());
                                auditList.setStatus(1);
                                auditList.setOpinion(eventJson.getString("remark"));
                                auditListService.updateById(auditList);
                                picking.setAuditStatus(3);
                                pickingService.update(picking, wrapper);
                                logs.info("拒绝审批->" + user_id + ":" + eventJson.getString("remark"));
                            }
                        }
                    }
                }

//                if (type.equals("terminate")) {
//                    //修改报销状态
//                    if (eventJson.getString("processCode").equals(Constants.ALLOCATION_PURCHASE_REIMBURSEMENT)) {
//
//
//                    }
//
//                }
            }
            //用户新增
            if ("user_add_org".equals(eventType)) {
                for (Object obj : JSON.parseArray(eventJson.getString("UserId"))) {
                    User user = new User();
                    JSONObject user_details = JSON.parseObject(DingDingUtil.queryUser(obj.toString(),
                            DingDingUtil.obtainToken())).getJSONObject("result");
                    System.out.println(user_details);
                    user.setUser_name(user_details.getString("name"));
                    user.setUserid(user_details.getString("userid"));
                    user.setUser_type(1);
                    user.setUser_title(user_details.getString("title"));
                    user.setDept_id(Integer.valueOf(((List) user_details.get("dept_id_list")).get(((List) user_details.get("dept_id_list")).size() - 1).toString()));
                    user.setUnionid(user_details.getString("unionid"));
                    user.setUser_mobile(Long.parseLong(user_details.getString("mobile")));
                    System.out.println(user);
                    userService.save(user);
                }
            }
            //用户信息修改
            if ("user_modify_org".equals(eventType)) {
                for (Object obj : JSON.parseArray(eventJson.getString("UserId"))) {
                    User user = new User();
                    JSONObject user_details = JSON.parseObject(DingDingUtil.queryUser(obj.toString(),
                            DingDingUtil.obtainToken())).getJSONObject("result");
                    user.setUser_name(user_details.getString("name"));
                    user.setUserid(user_details.getString("userid"));
                    user.setUser_type(1);
                    user.setUser_title(user_details.getString("title"));
                    user.setDept_id(Integer.valueOf(((List) user_details.get("dept_id_list")).get(((List) user_details.get("dept_id_list")).size() - 1).toString()));
                    user.setUnionid(user_details.getString("unionid"));
                    user.setUser_mobile(Long.parseLong(user_details.getString("mobile")));
                    UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.eq("userid", user_details.getString("userid"));
                    userService.saveOrUpdate(user, updateWrapper);
                }
            }
            // 5. 返回success的加密数据
            Map<String, String> successMap = callbackCrypto.getEncryptedMap("success",timeStamp,nonce);
            return successMap;
        } catch (DingCallbackCrypto.DingTalkEncryptException e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
        return null;
    }


    @ApiOperation(value = "获取钉钉人员信息")
    @GetMapping("/getPersonnelInformation")
    public ResultVo getPersonnelInformation(@PathVariable("username") String username) {
        if (username != null) {

        } else {
            // 返回所有的
        }
        return null;
    }

}
